import {
  _decorator,
  Animation,
  AnimationClip,
  assert,
  assetManager,
  CircleCollider2D,
  Collider2D,
  Component,
  Contact2DType,
  Input,
  instantiate,
  IPhysics2DContact,
  JsonAsset,
  Label,
  Node,
  PhysicsSystem2D,
  Prefab,
  RigidBody2D,
  Sprite,
  SpriteFrame,
} from "cc";
import { FruitNode } from "../Fruit/FruitNode";

const { ccclass, property } = _decorator;

@ccclass("Home")
export class Home extends Component {
  //水果预制体
  @property(Node)
  fruitNode: Prefab;
  //水果出现高度
  @property(Number)
  fruitStartH: number;
  //水果精灵图列表
  @property([SpriteFrame])
  fruitSps: SpriteFrame[];
  //顶部默认展示的水果
  @property(Sprite)
  defaultSprite: Sprite;
  //水果配置文件
  @property(JsonAsset)
  itemGiftJson: JsonAsset = null!;
  //分割线
  @property(Node)
  overLine: Node;
  //分数节点
  @property(Node)
  //结果弹窗
  overPopup: Node;
  @property(Label)
  ScoreLab: Label;
  //是否可以继续放置   true 可以   false 不可以
  private _isActive: boolean = true;
  //间隔时间
  private _time: number = 0.8;
  //游戏是否结束 true 结束  false 继续
  public _gameOver: boolean = false;
  //水果配置文件
  FRUIT_CONFIG: Object;
  //当前水果编号
  CURRENTID: number;
  //下一个水果编号
  NEXTID: number;

  protected onLoad(): void {}

  start() {
    // 获取到 Json 数据
    this.FRUIT_CONFIG = this.itemGiftJson.json;
    //监听鼠标点击事件
    // 添加鼠标点击事件监听
    this.node.on(Input.EventType.TOUCH_START, this.createPrefab, this);

    this.NEXTID = this.getRandomNumber(this.fruitSps.length);
    this.CURRENTID = this.getRandomNumber(this.fruitSps.length);
    //更新默认水果图标
    this.defaultSprite.spriteFrame = this.fruitSps[this.NEXTID];
    //更新放置信息
    this._isActive = true;
  }

  //在点击的位置创建新的预制体
  createPrefab(event) {
    //如果游戏结束  就不再检测
    if (this._gameOver) return;
    if (!this._isActive) return;
    // 切换下落
    this.CURRENTID = this.NEXTID;
    //获取鼠标位置
    var mousePosX = event.getUILocation().x;
    let fruit = instantiate(this.fruitNode);
    //设置精灵图
    let fruitSp = fruit.getComponent(Sprite);
    fruit.getComponent(FruitNode).fruitType = this.CURRENTID;
    fruit.getChildByName("id").getComponent(Label).string = String(
      this.CURRENTID
    );
    fruitSp.spriteFrame = this.fruitSps[this.CURRENTID];

    //动态设置碰撞半径
    let circleCollider = fruit.getComponent(CircleCollider2D);
    circleCollider.radius = fruitSp.node.width / 2;
    //监听两个物体接触
    circleCollider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
    //开启碰撞监听
    let rigidbody = fruit.getComponent(RigidBody2D);
    rigidbody.enabledContactListener = true;

    //设置起始位置
    fruit.setPosition(mousePosX, this.fruitStartH);
    fruit.parent = this.node;
    //展示节点
    fruit.active = true;
    //更新默认水果图标
    this.NEXTID = this.getRandomNumber(this.fruitSps.length);
    this.defaultSprite.spriteFrame = this.fruitSps[this.NEXTID];
    //打印当前水果信息
    console.log("当前水果信息：", this.FRUIT_CONFIG[this.NEXTID]);
    //更新状态
    this._isActive = false;
    this.scheduleOnce(() => {
      this._isActive = true;
    }, this._time);
  }

  //随机出现水果
  getRandomNumber(max: number) {
    // 生成一个 [0, 1) 之间的随机数
    var randomValue = Math.random();
    // 将随机数映射到 [0, 5) 范围
    var randomNumber = Math.floor(randomValue * max);
    return randomNumber;
  }
  //碰撞监听
  onBeginContact(
    selfCollider: Collider2D,
    otherCollider: Collider2D,
    contact: IPhysics2DContact | null
  ) {
    this.checkNodeSame(selfCollider.node, otherCollider.node);
    //有碰撞说明掉到底部了 然后更新放置状态
  }

  //判断两个碰撞的节点是否相同
  checkNodeSame(selfNode: Node, otherNode: Node) {
    //如果游戏结束  就不再检测
    if (this._gameOver) return;
    //判断是不是两个水果
    if (selfNode.name === "fruitNode" && otherNode.name === "fruitNode") {
      const selfNodeType = selfNode.getComponent(FruitNode).fruitType;
      const otherNodeType = otherNode.getComponent(FruitNode).fruitType;
      if (selfNodeType == otherNodeType) {
        selfNode.getComponent(RigidBody2D).enabledContactListener = false;
        otherNode.getComponent(RigidBody2D).enabledContactListener = false;

        // 播放动画;
        selfNode.getComponent(Animation).play();
        otherNode.getComponent(Animation).play();
        this.scheduleOnce(() => {
          //销毁
          selfNode.destroy();
          otherNode.destroy();
          //加分
          this.ScoreLab.string =
            Number(this.ScoreLab.string) +
            this.FRUIT_CONFIG[selfNodeType].score +
            this.FRUIT_CONFIG[otherNodeType].score;
        }, 0.5);
      }
    }
  }
  update(deltaTime: number) {}
}
